package hiresoft.network;

import java.io.OutputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * The output stream for the Network class.
 * Handles the transmission of data to the
 * server.
 *
 * @see Packets
 *
 * @author Filip Jaros
 */
public class NetOutputStream extends DataOutputStream
{
    /**
     * The output stream for sending data
     * to the server.
     */
    private ByteArrayOutputStream buffer;

    /**
     * Constructor for NetOutputStream.
     * 
     * @param out the {@link OutputStream}
     */
    public NetOutputStream(OutputStream out)
    {
        super(out);
        buffer = new ByteArrayOutputStream();
    }

    /**
     * Insert the next byte of data into
     * the output stream.
     *
     * @param data next byte of data to send
     * @throws IOException
     */
    public void Insert(byte data) throws IOException
    {
        buffer.write(data);
    }

    /**
     * Insert the next four bytes of
     * data to send to the server
     * (as a short).
     * 
     * @param data the next four bytes of data to send
     * @throws IOException
     */
    public void Insert(short data) throws IOException
    {
        buffer.write(data & 0x00FF);
        buffer.write((data & 0xFF00) >> 8);
    }

    /**
     * Inserts the next eight bytes
     * of data to send to the server
     * (as an int).
     *
     * @param data the next eight bytes as a string
     * @throws IOException
     */
    public void Insert(int data) throws IOException
    {
        buffer.write(data & 0x000000FF);
        buffer.write((data & 0x0000FF00) >> 8);
        buffer.write((data & 0x00FF0000) >> 16);
        buffer.write((data & 0xFF000000) >> 24);
    }

    /**
     * Inserts a string of data to
     * send to the server with a
     * terminator at the end (0).
     *
     * @param data the String to send to the server
     * @throws IOException
     */
    public void Insert(String data) throws IOException
    {
        data = data.replace("\'", "\'\'");
        buffer.write(data.getBytes());
        buffer.write(0);
    }

    /**
     * Sends the data to the server.  Includes
     * a packet ID, identified in {@link Packets}.
     * 
     * @param packetId the {@link Packets Packet} id.
     * @throws IOException if communication with server does not complete
     */
    public void Send(byte packetId) throws IOException
    {
        int size = buffer.size() + 6;
        byte[] header = new byte[size];
        header[0] = (byte)0xFF;
        header[1] = packetId;
        header[2] = (byte)(size & 0x000000FF);
        header[3] = (byte)((size & 0x0000FF00) >> 8);
        header[4] = (byte)((size & 0x00FF0000) >> 16);
        header[5] = (byte)((size & 0xFF000000) >> 24);
        System.arraycopy(buffer.toByteArray(), 0, header, 6, size - 6);
        buffer.reset();
        write(header);
    }
}